#ifndef OPCUACLIENT_H
#define OPCUACLIENT_H

#include <QObject>
#include <QMutex>
#include <QString>
#include <QMap>

#include "open62541.h"

class OPCUAClient : public QObject {
    Q_OBJECT
public:
    static OPCUAClient* instance();
    ~OPCUAClient();

    bool connectServer(const QString& endpointUrl = "opc.tcp://172.16.10.1:4840");
    void disconnectServer();
    bool isConnected() const;

    // 订阅 REAL 类型变量（西门子PLC）
    bool subscribeReal(const QString& nodeId, const QString& alias = "");
    void unsubscribeReal(const QString& nodeId);
    void unsubscribeAll();
signals:
    void realValueChanged(const QString& alias, float value);

private:
    explicit OPCUAClient(QObject* parent = 0);

    static void dataChangeCallback(
        UA_Client*, UA_UInt32, void*, UA_UInt32, void*, UA_DataValue*
        );

    void parseNodeId(const QString& nodeId, UA_NodeId& outNodeId);

    static UA_Client* m_client;
    static QMutex m_mutex;
public:
    bool m_connected;
    UA_UInt32 m_subscriptionId;
    QMap<UA_UInt32, QString> m_monitoredItems; // monitoredItemId -> alias
    QMap<QString, UA_UInt32> m_nodeIdMap;      // nodeId -> monitoredItemId
};

#endif // OPCUACLIENT_H
